<script setup lang="ts">
import Child from './Child.vue'
import { ref } from 'vue'

// const msg = ref('hello')
// const changeMsg = () => {
//     msg.value = '你好'
// }

// const handleChangeMsg = () => {
//     msg.value = '来自子组件的消息'
// }
// const flag = ref(true)

import { computed, watch } from 'vue'

// const sum1 = ref(0)
// const sum2 = ref(0)
// const sum = computed(() => {
//     return sum1.value + sum2.value
// })
// const sum3 = ref(0)

// watch(sum1, (newValue) => {
//     sum3.value = newValue * 2
// })

// const obj = ref({
//     name: '张三',
//     age: 18
// })

// const changeObj = () => {
//     obj.value.name = '李四'
//     obj.value.age = 20
// }

import { nextTick } from 'vue'

// 这个例子展示了Vue的异步更新和DOM渲染机制
// 适用场景:当我们需要在数据更新后立即获取更新后的DOM状态时
// 比如:
// 1. 在更新数据后需要基于新DOM计算元素尺寸
// 2. 在更新数据后需要重新设置第三方UI库的状态
// 3. 在更新数据后需要触发基于新DOM的动画效果
// const message = ref('原始消息')
// const updateMessage = async () => {
//     // 更新数据
//     message.value = '更新后的消息'

//     // 此时DOM还未更新,获取的仍是旧的内容
//     console.log('立即获取:', document.querySelector('.message').textContent)

//     // 等待DOM更新完成
//     await nextTick()
//     // 此时可以安全地获取更新后的DOM内容
//     console.log('nextTick后:', document.querySelector('.message').textContent)

//     // 这里可以进行任何依赖新DOM的操作
//     // 如:计算高度、触发动画等
// }
// reactive示例
// reactive适用于对象类型的响应式数据


// 修改reactive对象的方法
// const updateStudent = () => {
//     // 直接修改属性
//     student.name = '赵六'
//     student.age = 18

//     // 修改数组
//     student.hobbies.push('游泳')

//     // 修改嵌套对象
//     student.address.city = '上海'
// }

// reactive的局限性：
// 1. 只能用于对象类型(对象、数组、Map、Set等)
// 2. 不能解构，解构后会失去响应性
// const { name, age } = student // 这样会失去响应性

// ref 和 reactive 响应式对比示例
// const refObj = ref({
//     name: '小明',
//     info: {
//         age: 20,
//         hobby: '篮球'
//     }
// })

// const reactiveObj = reactive({
//     name: '小红',
//     info: {
//         age: 18,
//         hobby: '羽毛球'
//     }
// })

// const updateRefObj = () => {
//     // ref 需要 .value 来访问和修改
//     refObj.value.name = '小张'
//     // 直接修改深层属性也是响应式的,因为 ref 会自动对对象类型值使用 reactive
//     refObj.value.info.age = 22
// }

// const updateReactiveObj = () => {
//     // reactive 可以直接修改属性
//     reactiveObj.name = '小李'
//     // 同样支持深层响应式
//     reactiveObj.info.age = 25
// }

// // 区别在于如果我们替换整个对象:
// const replaceObjects = () => {
//     // ref 对整个对象的替换仍然是响应式的
//     refObj.value = {
//         name: '完全新的对象',
//         info: {
//             age: 30,
//             hobby: '游泳'
//         }
//     }

//     // reactive 不能直接替换整个对象,这样会丢失响应性
//     // reactiveObj = { ... } // 这样是错误的
//     // 需要逐个属性更新
//     Object.assign(reactiveObj, {
//         name: '逐个更新',
//         info: {
//             age: 28,
//             hobby: '跑步'
//         }
//     })
// }
// computed和方法的区别示例
// const count = ref({
//     val: 1
// })
// const price = ref(10)

// // computed 有缓存,只有依赖变化时才会重新计算
// const total = computed(() => {
//     console.log('computed 执行')
//     return count.value.val * price.value
// })

// // 方法每次调用都会重新执行
// const getTotal = () => {
//     console.log('方法执行') 
//     return count.value.val * price.value
// }

// const updateCount = () => {
//     count.value.val++
// }

// // 添加一个不相关的数据,用于触发模板重新渲染
// const unrelatedData = ref(0)
// const triggerRerender = () => {
//     unrelatedData.value++
// }

// 定义一个响应式的文字颜色变量
// const textColor = ref('black')

// // 点击按钮时切换颜色
// const changeColor = () => {
//     textColor.value = !textColor.value 
// }
// import { useTemplateRef, onMounted } from 'vue'

// // 第一个参数必须与模板中的 ref 值匹配
// const input = useTemplateRef('my-input')

// onMounted(() => {
//     input.value.focus()
// })


// Teleport 示例
// 用于将组件内容传送到指定的DOM位置
// 适用场景:模态框、通知提示、悬浮菜单等需要打破组件层级的场景

// const showModal = ref(true)

// const openModal = () => {
//     showModal.value = true
// }

// const closeModal = () => {
//     showModal.value = false
// }

// 在template中使用 teleport 将模态框传送到 body 下
// <teleport to="body"> 确保模态框总是在页面最顶层显示
// 避免被其他元素的 z-index 或 overflow 属性影响
// import { provide } from 'vue'

// const message = ref('hello')
// provide('message', message)

</script>

<template>


    <!-- <Child/> -->
    <!-- <teleport to="body">
        <div v-if="showModal" class="modal">
            <h2>模态框内容</h2>
            <p>这是模态框的内容</p>
            <button @click="closeModal">关闭</button>
        </div>
    </teleport> -->
    <!-- <input ref="my-input" /> -->
    <!-- <div>
        <div :class="{ 'text-color': textColor }">这是一段文字</div>
        <button @click="changeColor">改变颜色</button>
    </div> -->
    <!-- <div>
        <h3>computed和方法的区别示例:</h3>
        <p>数量: {{ count.val }}</p>
        <p>单价: {{ price }}</p>
        <p>总价(computed): {{ total }}</p>
        <p>总价(方法): {{ getTotal() }}</p>
        <button @click="updateCount">数量+1</button>
        <button @click="triggerRerender">触发重新渲染 ({{ unrelatedData }})</button>
        <p>说明: 点击"触发重新渲染"按钮时,computed的值不会重新计算,但方法会重新执行</p>
    </div> -->
    <!-- <div>
        <h3>ref对象示例：</h3>
        <p>姓名：{{ refObj.name }}</p>
        <p>年龄：{{ refObj.info.age }}</p>
        <p>爱好：{{ refObj.info.hobby }}</p>
        <button @click="updateRefObj">修改ref对象</button>
        
        <h3>reactive对象示例：</h3>
        <p>姓名：{{ reactiveObj.name }}</p>
        <p>年龄：{{ reactiveObj.info.age }}</p>
        <p>爱好：{{ reactiveObj.info.hobby }}</p>
        <button @click="updateReactiveObj">修改reactive对象</button>
        
        <button @click="replaceObjects">替换整个对象</button>
    </div> -->
    <!-- <div>
        <h3>学生信息：</h3>
        <p>姓名：{{ student.name }}</p>
        <p>年龄：{{ student.age }}</p>
        <p>爱好：{{ student.hobbies.join('、') }}</p>
        <p>地址：{{ student.address.city }} {{ student.address.district }}</p>
        <button @click="updateStudent">更新学生信息</button>
    </div> -->
    <!-- <div class="message">{{ message }}</div>
    <button @click="updateMessage">更新消息</button> -->
    <!-- <div>
        <p>姓名：{{ obj.name }}</p>
        <p>年龄：{{ obj.age }}</p>
        <button @click="changeObj">修改信息</button>
    </div> -->
    <!-- {{ sum }}
    {{ sum3 }}
    <div>
        <input type="number" v-model="sum1" placeholder="请输入第一个数">
        <input type="number" v-model="sum2" placeholder="请输入第二个数">
    </div>
    <Child :msg="msg" @change-msg="handleChangeMsg" v-if="flag"></Child>
    <button @click="changeMsg">改变消息</button>
    <button @click="flag = !flag">{{ flag ? '隐藏' : '显示' }}子组件</button> -->
</template>

<style scoped>
.text-color {
    color: red;
}
</style>
